package com.fy.fyspace.controller;

import com.fy.fyspace.common.annotation.GlobalInterceptor;
import com.fy.fyspace.common.result.PageResult;
import com.fy.fyspace.common.result.Result;
import com.fy.fyspace.common.utils.StringTools;
import com.fy.fyspace.constant.KeysConstant;
import com.fy.fyspace.constant.ResultMessageConstant;
import com.fy.fyspace.mapper.FileInfoMapper;
import com.fy.fyspace.model.dto.file.FileQueryDTO;
import com.fy.fyspace.model.dto.file.RenameFileDTO;
import com.fy.fyspace.model.dto.file.UploadFileDTO;
import com.fy.fyspace.model.entity.FileInfo;
import com.fy.fyspace.model.vo.file.FileStatisticsVO;
import com.fy.fyspace.model.vo.file.FileTypeVO;
import com.fy.fyspace.model.vo.file.FolderVO;
import com.fy.fyspace.model.vo.file.UploadResultVO;
import com.fy.fyspace.model.vo.user.UserSessionVO;
import com.fy.fyspace.service.FileInfoService;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 文件信息 前端控制器
 * </p>
 *
 * @author fwq
 * @since 2025-03-03
 */
@Slf4j
@RestController
@RequestMapping("/fileInfo")
@Tag(name = "普通文件模块接口")
public class FileInfoController extends BaseController {
    @Autowired
    private FileInfoService fileInfoService;

    @Autowired
    private FileInfoMapper fileInfoMapper;
//    @Resource
//    private FileDownloadService fileDownloadService;
    
    /**
     * 上传文件
     */
    @PostMapping("/uploadFile")
    @GlobalInterceptor
    @Operation(summary = "上传文件")
    public Result uploadFile(HttpSession session, UploadFileDTO uploadFileDTO) {
        // 1. 参数校验
        if (uploadFileDTO == null || uploadFileDTO.getFile() == null) {
            return Result.error("上传文件不能为空");
        }
        if (StringUtils.isBlank(uploadFileDTO.getChunkIndex()) || StringUtils.isBlank(uploadFileDTO.getChunks())) {
            return Result.error("分片参数不能为空");
        }

        UserSessionVO userSessionVO = (UserSessionVO) session.getAttribute(KeysConstant.LOGIN_SESSION_KEY);
        if (userSessionVO == null) {
            return Result.error("用户未登录");
        }

        try {
            log.info("开始处理文件上传请求 - 文件名: {}, 分片: {}/{}, MD5: {}", 
                    uploadFileDTO.getFileName(), 
                    uploadFileDTO.getChunkIndex(), 
                    uploadFileDTO.getChunks(),
                    uploadFileDTO.getFileMd5());

            String uploadId = fileInfoService.uploadFile(userSessionVO, uploadFileDTO);
            UploadResultVO uploadResultVO = new UploadResultVO();

            // 处理返回结果
            if (uploadId != null) {
                // 分片上传中
                uploadResultVO.setStatus(ResultMessageConstant.UPLOADING);
                uploadResultVO.setFileId(uploadId);
            } else if ("0".equals(uploadFileDTO.getChunkIndex())) {
                // 秒传成功
                uploadResultVO.setStatus(ResultMessageConstant.UPLOAD_SECONDS);
                uploadResultVO.setFileId(null);
            } else {
                // 上传完成
                uploadResultVO.setStatus(ResultMessageConstant.UPLOAD_SUCCESS);
                uploadResultVO.setFileId(null);
            }

            log.info("文件上传请求处理完成 - 文件名: {}, 状态: {}", 
                    uploadFileDTO.getFileName(), 
                    uploadResultVO.getStatus());
            return Result.success(uploadResultVO);
        } catch (Exception e) {
            log.error("文件上传失败 - 文件名: {}, 分片: {}/{}", 
                    uploadFileDTO.getFileName(), 
                    uploadFileDTO.getChunkIndex(), 
                    uploadFileDTO.getChunks(), 
                    e);
            return Result.error("文件上传失败: " + e.getMessage());
        }
    }

    /**
     * 根据条件文件分页查询
     */
    @GetMapping("/loadDataList")
    @GlobalInterceptor
    @Operation(summary = "根据条件文件分页查询")
    public Result<PageResult> loadDataList(HttpSession session, FileQueryDTO queryDTO) {
        log.info("queryDTO:{}", queryDTO);
        UserSessionVO userSessionVO = (UserSessionVO) session.getAttribute(KeysConstant.LOGIN_SESSION_KEY);
        PageResult pageResult = fileInfoService.filePageQuery(queryDTO, userSessionVO);
        log.info("返回数据封装:{}", pageResult);
        return Result.success(pageResult);
    }

    /**
     * 查看文件
     */
    @GetMapping("/getFile/{fileId}")
    @GlobalInterceptor
    @Operation(summary = "查看文件")
    public void getFile(HttpServletResponse response, @PathVariable String fileId) {
        FileInfo fileInfo = fileInfoService.getFilePath(fileId);
        readFile(response, fileInfo.getFilePath());
    }

    /**
     * 文件列表浏览视频
     */
    @GetMapping("/ts/getVideoInfo/{fileId}")
    @GlobalInterceptor
    @Operation(summary = "文件列表浏览视频")
    public void getVideoInfo(HttpServletResponse response, @PathVariable String fileId) {
        log.info("getVideoInfo:{}", fileId);
        FileInfo fileInfo = fileInfoService.getFilePath(fileId);
        log.info("URL:{}", fileInfo.getFilePath());
        readFile(response, fileInfo.getFilePath());
    }

    /**
     * 删除文件
     */
    @PostMapping("/delFile")
    @GlobalInterceptor
    @Operation(summary = "删除文件")
    public Result delFile(@RequestParam("fileIds") String fileIdList) {
        log.info("批量删除文件id接收:{}", fileIdList);
        fileInfoService.delFile(fileIdList);
        return Result.success();
    }

    /**
     * 重命名文件
     */
    @PostMapping("/rename")
    @GlobalInterceptor
    @Operation(summary = "重命名文件")
    public Result rename(@RequestBody RenameFileDTO renameFileDTO) {
        log.info("重命名文件接收:{}", renameFileDTO);
        fileInfoService.rename(renameFileDTO);
        return Result.success();
    }

    /**
     * 创建文件下载路径
     */
    @PostMapping("/createDownloadUrl/{code}")
    @GlobalInterceptor
    @Operation(summary = "创建文件下载路径")
    public Result createDownloadUrl(@PathVariable("code") String fileId) {
        return Result.success(fileInfoService.createDownloadURL(fileId));
    }

    /**
     * 获取文件图标
     */
    @GetMapping("/getImage/{imageFolder}/{imageName}")
    @GlobalInterceptor
    @Operation(summary = "获取文件图标")
    public void getImage(HttpServletResponse response, @PathVariable("imageFolder") String fileId,
                         @PathVariable("imageName") String fileName) {
        log.info("fileId,fileName:{},{}", fileId, fileName);
        if (StringTools.isEmpty(fileId) || StringUtils.isBlank(fileId)) {
            return;
        }

        String imageSuffix = StringTools.getFileSuffix(fileName);
        String filePath = fileInfoMapper.selectById(fileId).getFileCover();
        imageSuffix = imageSuffix.replace(".", "");
        String contentType = "image/" + imageSuffix;
        response.setContentType(contentType);
        response.setHeader("Cache-Control", "max-age=2592000");
        readFile(response, filePath);
    }

    /**
     * 创建文件夹
     */
    @PostMapping("/newFoloder")
    @GlobalInterceptor
    @Operation(summary = "创建文件夹")
    public Result newFoloder(HttpSession session, String filePid, String fileName) {
        UserSessionVO userSessionVO = (UserSessionVO) session.getAttribute(KeysConstant.LOGIN_SESSION_KEY);
        FileInfo fileInfo = fileInfoService.newFolder(filePid, fileName, userSessionVO);
        log.info("filePid,fileName:{},{}", filePid, fileName);
        return Result.success(fileInfo);
    }

    /**
     * 获取文件夹信息
     */
    @PostMapping("/getFolderInfo")
    @GlobalInterceptor
    @Operation(summary = "获取文件夹信息")
    public Result getFolderInfo(@RequestParam("path") String fileId) {
        log.info("fileId:{}", fileId);
        List<FolderVO> folderInfo = fileInfoService.getFolderInfo(fileId);
        return Result.success(folderInfo);
    }

    /**
     * 获取文件夹
     */
    @PostMapping("/loadAllFolder")
    @GlobalInterceptor
    @Operation(summary = "获取文件夹")
    public Result loadAllFolder(HttpSession session, String filePid, String currentFileIds) {
        log.info("filePid,currentFileIds:{},{}", filePid, currentFileIds);
        List<FileInfo> fileInfoList = fileInfoService
                .loadAllFolder((UserSessionVO) session.getAttribute(KeysConstant.LOGIN_SESSION_KEY), filePid,
                        currentFileIds);
        return Result.success(fileInfoList);
    }

    /**
     * 移动文件
     */
    @PostMapping("/changeFileFolder")
    @GlobalInterceptor
    @Operation(summary = "移动文件")
    public Result changeFileFolder(String fileIds, String filePid) {
        fileInfoService.changeFileFolder(fileIds, filePid);
        return Result.success();
    }

    /**
     * 获取文件统计信息
     */
    @PostMapping("/statistics")
    @GlobalInterceptor
    @Operation(summary = "获取文件统计信息")
    public Result<FileStatisticsVO> getFileStatistics(HttpSession session) {
        UserSessionVO userSessionVO = (UserSessionVO) session.getAttribute(KeysConstant.LOGIN_SESSION_KEY);
        FileStatisticsVO statistics = fileInfoService.getFileStatistics(Math.toIntExact(userSessionVO.getId()));
        return Result.success(statistics);
    }

    /**
     * 获取文件类型分布
     */
    @PostMapping("/typeDistribution")
    @GlobalInterceptor(checkLogin = true)
    @Operation(summary = "获取文件类型分布")
    public Result getFileTypeDistribution(HttpSession session) {
        List<FileTypeVO> distribution = new ArrayList<>();
        addFileTypeDistribution(distribution, "图片", 60, 0.44);
        addFileTypeDistribution(distribution, "视频", 160, 0.5);
        addFileTypeDistribution(distribution, "文件", 16, 0.7);
        addFileTypeDistribution(distribution, "压缩包", 20, 0.2);
        addFileTypeDistribution(distribution, "音乐", 16, 0.31);
        addFileTypeDistribution(distribution, "其他", 19, 0.1);
        return Result.success(distribution);
    }

    private void addFileTypeDistribution(List<FileTypeVO> distribution, String type, int count, double percentage) {
        FileTypeVO fileTypeVO = new FileTypeVO();
        fileTypeVO.setType(type);
        fileTypeVO.setCount(count);
        fileTypeVO.setPercentage(percentage);
        distribution.add(fileTypeVO);
    }

    /**回收站文件分页查询
     *
     * @param pageNo
     * @param PageSize
     * @param httpSession
     * @return
     */

    @PostMapping("/loadRecycleList")
    @ApiOperation(value = "获取回收站列表", notes = "分页获取回收站文件列表")
    @GlobalInterceptor
    public Result loadRecycleList(Integer pageNo, Integer PageSize,
            @ApiParam(hidden = true) HttpSession httpSession) {
        UserSessionVO userSessionVO = (UserSessionVO) httpSession.getAttribute(KeysConstant.LOGIN_SESSION_KEY);
        PageResult pageResult = fileInfoService.loadRecycleList(pageNo,PageSize, userSessionVO);
        log.info("返回的回收站数据为:{}", pageResult);
        return Result.success(pageResult);
    }

    /**
     * 恢复删除文件
     *
     * @param fileIdList
     * @return
     */
    @PostMapping("/recoverFile")
    @ApiOperation(value = "恢复文件", notes = "从回收站恢复文件")
    @GlobalInterceptor
    public Result recoverFile(
            @ApiParam(value = "文件ID列表", required = true) @RequestParam("fileIds") List<String> fileIdList) {
        log.info("恢复删除fileIds:{}", fileIdList);
        fileInfoService.recoverFile(fileIdList);
        return Result.success();
    }

    /**
     * 永久删除回收站文件
     *
     * @param delFileList
     * @return
     */
    @PostMapping("/delRecycleFile")
    @ApiOperation("永久删除回收站文件")
    @GlobalInterceptor
    public Result delRecycleFile(@RequestParam("fileIds") List<String> delFileList, HttpSession httpSession) {
        UserSessionVO userSessionVO = (UserSessionVO) httpSession.getAttribute(KeysConstant.LOGIN_SESSION_KEY);
        log.info("回收站文件删除接收信息:{}", delFileList);
        fileInfoService.delRecycleFile(delFileList, userSessionVO);
        return Result.success();
    }

    /**
     * 下载文件（带限流）
     */
//    @GetMapping("/download/{fileId}")
//    @GlobalInterceptor
//    @Operation(summary = "下载文件（带限流）")
//    public void downloadFile(@PathVariable String fileId, HttpServletResponse response, HttpSession session) {
//        UserSessionVO userSessionVO = (UserSessionVO) session.getAttribute(KeysConstant.LOGIN_SESSION_KEY);
//        FileInfo fileInfo = fileInfoService.getFilePath(fileId);
//        if (fileInfo == null) {
//            throw new ConditionException(ResultMessageConstant.FILE_NOT_FOUND);
//        }
//
//        UserRoleEnum userRole = userSessionVO.getUserRole() != null ?
//                UserRoleEnum.getEnumByType(userSessionVO.getUserRole()) :
//                UserRoleEnum.USER;
//
//        fileDownloadService.downloadFile(fileInfo, userRole, userSessionVO, response);
//    }
}
